import 'dart:math';

import 'package:flutter/material.dart';
import 'package:x3_charts_core/model/base_chart_info_model.dart';

///**
///* @author hrongyong
///* @date   2/4/21
///* @email hrongyong@gmail.com
///* Description: 图表通用工具
///*/

class ChartTools {
  ///圆型结构图表文字偏移 - 可以规划出象限的
  ///
  ///输入：offset-绘制的位置的起点，textSize - 主标题的size，subTextSize-副标题
  ///
  ///输出：List<Offset>  - textSize: List[0]   subTextSize: List[1]
  static List<Offset> roundStructureTextOffset({@required Offset offset, @required Size textSize, Size subTextSize}) {
    Offset textOffsetPos;
    Offset subTextOffsetPos;

    ///判断标题更宽还是副标题更宽
    ///主要处理第一第二象限和x轴上当副标题比标题长的时候，会有遮盖的问题
    bool isWiderTitle = true;
    if (subTextSize != null) {
      isWiderTitle = textSize.width > subTextSize.width;
    }

    ///由于存在浮点数的比较有精度问题（0.1 + 0.2 = 0.30000000000000004） 所以原来的 x == 0 改为 0<x<0.1
    ///x y轴偏移正负0.1
    ///文字偏移 x轴右为正 y轴下为正
    if (offset.dx > 0.1 && offset.dy < -0.1) {
      ///第一象限
      if (subTextSize != null) {
        if (isWiderTitle) {
          textOffsetPos = Offset(offset.dx, offset.dy - textSize.height);
          subTextOffsetPos = Offset(offset.dx + (textSize.width / 2 - subTextSize.width / 2), offset.dy);
        } else {
          textOffsetPos = Offset(offset.dx + subTextSize.width / 2 - textSize.width / 2, offset.dy - textSize.height);
          subTextOffsetPos = Offset(offset.dx, offset.dy);
        }
      } else {
        textOffsetPos = Offset(offset.dx, offset.dy - textSize.height);
      }
    } else if ((offset.dx >= -0.1 && offset.dx <= 0.1) && offset.dy < 0.1) {
      ///y轴负半轴
      if (subTextSize != null) {
        textOffsetPos = Offset(offset.dx - textSize.width / 2, offset.dy - textSize.height - subTextSize.height);
        subTextOffsetPos = Offset(offset.dx - subTextSize.width / 2, offset.dy - subTextSize.height);
      } else {
        textOffsetPos = Offset(offset.dx - textSize.width / 2, offset.dy - textSize.height);
      }
    } else if (offset.dx < -0.1 && offset.dy < -0.1) {
      ///第二象限
      if (subTextSize != null) {
        if (isWiderTitle) {
          textOffsetPos = Offset(offset.dx - textSize.width, offset.dy - textSize.height);
          subTextOffsetPos = Offset(offset.dx - textSize.width / 2 - subTextSize.width / 2, offset.dy);
        } else {
          textOffsetPos = Offset(offset.dx - subTextSize.width / 2 - textSize.width / 2, offset.dy - textSize.height);
          subTextOffsetPos = Offset(offset.dx - subTextSize.width, offset.dy);
        }
      } else {
        textOffsetPos = Offset(offset.dx - textSize.width, offset.dy - textSize.height / 2);
      }
    } else if (offset.dx < 0.1 && (offset.dy >= -0.1 && offset.dy <= 0.1)) {
      ///x轴负半轴
      if (subTextSize == null) {
        textOffsetPos = Offset(offset.dx - textSize.width, offset.dy - textSize.height / 2);
      } else {
        if (isWiderTitle) {
          textOffsetPos = Offset(offset.dx - textSize.width, offset.dy - textSize.height);
          subTextOffsetPos = Offset(offset.dx - textSize.width / 2 - subTextSize.width / 2, offset.dy);
        } else {
          textOffsetPos = Offset(offset.dx - textSize.width / 2 - subTextSize.width / 2, offset.dy - textSize.height);
          subTextOffsetPos = Offset(offset.dx - subTextSize.width, offset.dy);
        }
      }
    } else if (offset.dx < -0.1 && offset.dy > 0.1) {
      ///第三象限

      if (subTextSize != null) {
        if (isWiderTitle) {
          textOffsetPos = Offset(offset.dx - textSize.width, offset.dy);
          subTextOffsetPos = Offset(offset.dx - textSize.width / 2 - subTextSize.width / 2, offset.dy + textSize.height);
        } else {
          textOffsetPos = Offset(offset.dx - textSize.width, offset.dy);
          subTextOffsetPos = Offset(offset.dx - textSize.width / 2 - subTextSize.width / 2, offset.dy + textSize.height);
        }
      } else {
        textOffsetPos = Offset(offset.dx - textSize.width, offset.dy);
      }
    } else if ((offset.dx >= -0.1 && offset.dx <= 0.1) && offset.dy > -0.1) {
      ///y轴正半轴
      if (subTextSize == null) {
        textOffsetPos = Offset(offset.dx - textSize.width / 2, offset.dy);
      } else {
        if (isWiderTitle) {
          textOffsetPos = Offset(offset.dx - textSize.width / 2, offset.dy);
          subTextOffsetPos = Offset(offset.dx - subTextSize.width / 2, offset.dy + textSize.height);
        } else {
          textOffsetPos = Offset(offset.dx - textSize.width / 2, offset.dy);
          subTextOffsetPos = Offset(offset.dx - subTextSize.width / 2, offset.dy + textSize.height);
        }
      }
    } else if (offset.dx > 0.1 && offset.dy > 0.1) {
      ///第四象限
      if (subTextSize != null) {
        textOffsetPos = Offset(offset.dx, offset.dy);
        subTextOffsetPos = Offset(offset.dx + (textSize.width / 2 - subTextSize.width / 2), offset.dy + textSize.height);
      } else {
        textOffsetPos = Offset(offset.dx, offset.dy);
      }
    } else if (offset.dx > -0.1 && (offset.dy >= -0.1 && offset.dy <= 0.1)) {
      ///x轴正半轴
      if (subTextSize != null) {
        if (isWiderTitle) {
          textOffsetPos = Offset(offset.dx, offset.dy - textSize.height);
          subTextOffsetPos = Offset(offset.dx + (textSize.width / 2 - subTextSize.width / 2), offset.dy);
        } else {
          textOffsetPos = Offset(offset.dx + subTextSize.width / 2 - textSize.width / 2, offset.dy - textSize.height);
          subTextOffsetPos = Offset(offset.dx, offset.dy);
        }
      } else {
        textOffsetPos = Offset(offset.dx, offset.dy - textSize.height / 2);
      }
    } else {
      print("其他 - $offset");
      textOffsetPos = Offset(offset.dx - textSize.width / 2, offset.dy - textSize.height - subTextSize.height);
      if (subTextSize != null) {
        subTextOffsetPos = Offset(offset.dx - subTextSize.width / 2, offset.dy - subTextSize.height);
      }
    }

    return subTextSize != null ? <Offset>[textOffsetPos, subTextOffsetPos] : <Offset>[textOffsetPos];
  }

  ///圆型结构图表文字偏移 - 可以规划出象限的 - 当且仅当有三个标题要显示的时候用该方法
  ///
  ///输入：offset-绘制的位置的起点，textSize - 主标题的size，subTextSize-副标题
  ///
  ///输出：List<Offset>  - firstOffset: List[0]   secondOffset: List[1]  thirdOffset: List[2]
  static List<Offset> roundStructureThreeHeadingsOffset({@required Offset offset, @required Size firstSize, @required Size secondSize, @required Size thirdSize}) {
    Offset firstOffset;
    Offset secondOffset;
    Offset thirdOffset;
    double gapHeight = 0.0;

    ///最大宽度 - 所有的位置都要经过该值处理
    ///主要处理第一第二象限和x轴上当副标题比标题长的时候，会有遮盖的问题
    double maxWidth = 0.0;
    maxWidth = max(firstSize.width, max(secondSize.width, thirdSize.width));

    ///最上面的高度 = 三个size的高度 + 两个空隙高度
    double firstHeight = firstSize.height + secondSize.height + thirdSize.height + gapHeight * 2;

    ///中间的高度 = 二个size的高度 + 一个空隙高度
    double secondHeight = secondSize.height + thirdSize.height + gapHeight;

    ///最下面的高度 = -个size的高度
    double thirdHeight = thirdSize.height;

    ///由于存在浮点数的比较有精度问题（0.1 + 0.2 = 0.30000000000000004） 所以原来的 x == 0 改为 0<x<0.1
    ///x y轴偏移正负0.1
    ///文字偏移 x轴右为正 y轴下为正
    if (offset.dx > 0.1 && offset.dy < -0.1) {
      ///第一象限
      firstOffset = Offset(offset.dx + (maxWidth / 2 - firstSize.width / 2), offset.dy - firstHeight);
      secondOffset = Offset(offset.dx + (maxWidth / 2 - secondSize.width / 2), offset.dy - secondHeight);
      thirdOffset = Offset(offset.dx + (maxWidth / 2 - thirdSize.width / 2), offset.dy - thirdHeight);
    } else if ((offset.dx >= -0.1 && offset.dx <= 0.1) && offset.dy < 0.1) {
      ///y轴负半轴
      firstOffset = Offset(offset.dx - firstSize.width / 2, offset.dy - firstHeight);
      secondOffset = Offset(offset.dx - secondSize.width / 2, offset.dy - secondHeight);
      thirdOffset = Offset(offset.dx - thirdSize.width / 2, offset.dy - thirdHeight);
    } else if (offset.dx < -0.1 && offset.dy < -0.1) {
      ///第二象限
      firstOffset = Offset(offset.dx - firstSize.width - (maxWidth / 2 - firstSize.width / 2), offset.dy - firstHeight);
      secondOffset = Offset(offset.dx - secondSize.width - (maxWidth / 2 - secondSize.width / 2), offset.dy - secondHeight);
      thirdOffset = Offset(offset.dx - thirdSize.width - (maxWidth / 2 - thirdSize.width / 2), offset.dy - thirdHeight);
    } else if (offset.dx < 0.1 && (offset.dy >= -0.1 && offset.dy <= 0.1)) {
      ///x轴负半轴
      firstOffset = Offset(offset.dx - firstSize.width - (maxWidth / 2 - firstSize.width / 2), offset.dy - firstSize.height - (firstHeight / 2 - firstSize.height));
      secondOffset = Offset(offset.dx - secondSize.width - (maxWidth / 2 - secondSize.width / 2), offset.dy - secondSize.height / 2);
      thirdOffset = Offset(offset.dx - thirdSize.width - (maxWidth / 2 - thirdSize.width / 2), offset.dy + (firstHeight / 2 - thirdSize.height));
    } else if (offset.dx < -0.1 && offset.dy > 0.1) {
      ///第三象限

      firstOffset = Offset(offset.dx - firstSize.width - (maxWidth / 2 - firstSize.width / 2), offset.dy);
      secondOffset = Offset(offset.dx - secondSize.width - (maxWidth / 2 - secondSize.width / 2), offset.dy + firstSize.height + gapHeight);
      thirdOffset = Offset(offset.dx - thirdSize.width - (maxWidth / 2 - thirdSize.width / 2), offset.dy + firstSize.height + secondSize.height + gapHeight * 2);
    } else if ((offset.dx >= -0.1 && offset.dx <= 0.1) && offset.dy > -0.1) {
      ///y轴正半轴
      firstOffset = Offset(offset.dx - firstSize.width / 2, offset.dy);
      secondOffset = Offset(offset.dx - secondSize.width / 2, offset.dy + firstSize.height + gapHeight);
      thirdOffset = Offset(offset.dx - thirdSize.width / 2, offset.dy + firstSize.height + secondSize.height + gapHeight * 2);
    } else if (offset.dx > 0.1 && offset.dy > 0.1) {
      ///第四象限
      firstOffset = Offset(offset.dx + (maxWidth / 2 - firstSize.width / 2), offset.dy);
      secondOffset = Offset(offset.dx + (maxWidth / 2 - secondSize.width / 2), offset.dy + firstSize.height + gapHeight);
      thirdOffset = Offset(offset.dx + (maxWidth / 2 - thirdSize.width / 2), offset.dy + firstSize.height + secondSize.height + gapHeight * 2);
    } else if (offset.dx > -0.1 && (offset.dy >= -0.1 && offset.dy <= 0.1)) {
      ///x轴正半轴
      firstOffset = Offset(offset.dx + (maxWidth / 2 - firstSize.width / 2), offset.dy - (firstHeight / 2 - firstSize.height) - firstSize.height);
      secondOffset = Offset(offset.dx + (maxWidth / 2 - secondSize.width / 2), offset.dy - secondSize.height / 2);
      thirdOffset = Offset(offset.dx + (maxWidth / 2 - thirdSize.width / 2), offset.dy + (firstHeight / 2 - thirdSize.height));
    } else {
      print("其他 - $offset");
      firstOffset = Offset(offset.dx, offset.dy);
      secondOffset = Offset(offset.dx, offset.dy);
      thirdOffset = Offset(offset.dx, offset.dy);
    }

    return <Offset>[firstOffset, secondOffset, thirdOffset];
  }

  static num degToRad(num deg) => deg * (pi / 180.0);

  static num radToDeg(num rad) => rad * (180.0 / pi);

  ///求出来的结果是弧度值（另：角度值=弧度*180/π）
  static double getAngleByThreeP({@required Offset a, @required Offset b, @required Offset c}) {
    double a_b_x = a.dx - b.dx;
    double a_b_y = a.dy - b.dy;
    double c_b_x = c.dx - b.dx;
    double c_b_y = c.dy - b.dy;
    double ab_mul_cb = a_b_x * c_b_x + a_b_y * c_b_y;
    double dist_ab = sqrt(a_b_x * a_b_x + a_b_y * a_b_y);
    double dist_cd = sqrt(c_b_x * c_b_x + c_b_y * c_b_y);
    double cosValue = ab_mul_cb / (dist_ab * dist_cd);
    return acos(cosValue);
  }

  ///计算最大值 最大为千万位
  static double calculateTheMaximum(double value) {
    ///十位
    if (value > 10 && value <= 100) {
      if (value < 50) {
        return value % 10 == 0.0 ? value : (value ~/ 10) * 10.0 + (value % 10).toInt() + 1;
      } else {
        return value % 10 == 0.0 ? value : (value ~/ 10) * 10.0 + 10;
      }
    }

    ///百位
    if (value > 100 && value <= 1000) return value % 100 == 0.0 ? value : (value ~/ 10) * 10 + 10.0;

    ///千位
    if (value > 1000 && value <= 10000) return value % 1000 == 0.0 ? value : (value ~/ 100) * 100 + 100.0;

    ///万位
    if (value > 10000 && value <= 10 * 10000) return value % 10000 == 0.0 ? value : (value ~/ 1000) * 1000 + 1000.0;

    ///十万位
    if (value > 10 * 10000 && value <= 100 * 10000) return value % (10 * 10000) == 0.0 ? value : (value ~/ 10000) * 10000 + 10000.0;

    ///百万位
    if (value > 100 * 10000 && value <= 1000 * 10000) return value % (100 * 10000) == 0.0 ? value : (value ~/ (10 * 10000)) * 10 * 10000 + 10 * 10000.0;

    ///千万位
    if (value > 1000 * 10000 && value <= 10000 * 10000) return value % (1000 * 10000) == 0.0 ? value : (value ~/ (100 * 10000)) * 100 * 10000 + 100 * 10000.0;

    ///小目标
    if (value > 10000 * 10000 && value <= 10 * 10000 * 10000) return value % (10000 * 10000) == 0.0 ? value : (value ~/ (1000 * 10000)) * 1000 * 10000 + 1000 * 10000.0;

    ///十个小目标
    if (value > 10 * 10000 * 10000 && value <= 100 * 10000 * 10000) return value % (10 * 10000 * 10000) == 0.0 ? value : (value ~/ (10000 * 10000)) * 10000 * 10000 + 10000 * 10000.0;

    ///一百个小目标
    if (value > 100 * 10000 * 10000 && value <= 1000 * 10000 * 10000) return value % (100 * 10000 * 10000) == 0.0 ? value : (value ~/ (10 * 10000 * 10000)) * 10 * 10000 * 10000 + 10 * 10000 * 10000.0;

    ///个位
    return 10;
  }

  ///现有逻辑当直方图数值为负数的时候，其直方的比例直接就是1.0,然后颜色变换为警告颜色
  ///警告提醒⚠️⏰:只处理正数，也就是first、second、third为负数的时候是不处理的直接变为0
  ///直方图获取最大值
  static double getBaseHistogramChartInfo(List<BaseHistogramChartModel> chartInfo, {bool isSum = true}) {
    if (chartInfo == null || chartInfo.length == 0) return 1.0;
    double maxValue = 0.0;
    List<BaseHistogramChartModel> list = [];
    list.addAll(chartInfo);
    list.sort((a, b) => (a.first + a.second + a.third).compareTo(b.first + b.second + b.third));
    if (isSum) {
      maxValue = list[list.length - 1].first + list[list.length - 1].second + list[list.length - 1].third;
    } else {
      maxValue = max(list[list.length - 1].first, max(list[list.length - 1].second, list[list.length - 1].third));
    }
    maxValue = maxValue == 0.0 ? 1.0 : maxValue;
    return maxValue;
  }

  ///获取直方图基本信息 最大值:maxValue 最小值:minValue 偏移值:offsetValue 真实的最大值 trueMaximum
  ///现有逻辑 折线为负数时，向上偏移到显示的区域内，所以minValue为0% maxValue为100%
  ///offsetValue的作用是数值的偏移量
  static Map<String, dynamic> getBaseLineChartInfo(List<BaseLineChartModel> lineChartInfo) {
    if (lineChartInfo == null || lineChartInfo.length == 0) return {"maxValue": 1.0, "minValue": 0.0, "offsetValue": 0.0, "trueMaximum": 0.0};
    double maxValue = 0.0;
    double minValue = 0.0;
    double offsetValue = 0.0;
    double trueMaximum = 0.0;
    List<BaseLineChartModel> list = [];
    list.addAll(lineChartInfo);
    list.sort((a, b) => (max(a.third, max(a.first, a.second))).compareTo(max(b.third, max(b.first, b.second))));
    maxValue = max(list[list.length - 1].third, max(list[list.length - 1].first, list[list.length - 1].second));
    trueMaximum = maxValue;
    list.sort((a, b) => (min(a.third, min(a.first, a.second))).compareTo(min(b.third, min(b.first, b.second))));
    minValue = min(list[0].third, min(list[0].first, list[0].second));
    offsetValue = minValue.abs();

    ///保证maxValue为非零
    if (maxValue == 0.0 && minValue == 0.0) maxValue = 1.0;
    if (maxValue > 0.0 && minValue >= 0.0) return {"maxValue": maxValue, "minValue": minValue, "offsetValue": 0.0, "trueMaximum": trueMaximum};
    if (maxValue > 0.0 && minValue < 0) return {"maxValue": maxValue + minValue.abs(), "minValue": minValue, "offsetValue": offsetValue, "trueMaximum": trueMaximum};
    if (maxValue <= 0.0 && minValue < 0) return {"maxValue": minValue.abs(), "minValue": minValue, "offsetValue": offsetValue, "trueMaximum": trueMaximum};

    return {"maxValue": 1.0, "minValue": 0.0, "offsetValue": 0.0, "trueMaximum": trueMaximum};
  }

  ///由于绘画坐标是Y轴下半轴为正所以contains的规则要修改
  ///原来：offset.dx >= left && offset.dx < right && offset.dy >= top && offset.dy < bottom
  ///修改后：offset.dx >= left && offset.dx < right && offset.dy <= top && offset.dy > bottom
  static bool contains(Rect rect, Offset offset) {
    return offset.dx >= rect.left && offset.dx < rect.right && offset.dy <= rect.top && offset.dy > rect.bottom;
  }

  ///得到最大值
  static double getTheMaximum({Size a, Size b, Size c, Size d, Size e, Size f}) {
    double maximum = 0.0;
    if (a != null) maximum = max(maximum, a.width);
    if (b != null) maximum = max(maximum, b.width);
    if (c != null) maximum = max(maximum, c.width);
    if (d != null) maximum = max(maximum, d.width);
    if (e != null) maximum = max(maximum, e.width);
    if (f != null) maximum = max(maximum, f.width);
    return maximum;
  }

  ///得到合计
  static double getTheTotal({Size a, Size b, Size c, Size d, Size e, Size f, double spacing = 0.0}) {
    double total = 0.0;
    if (a != null) total = total + a.height;
    if (a != null) total = total + spacing;
    if (b != null) total = total + b.height;
    if (b != null) total = total + spacing;
    if (c != null) total = total + c.height;
    if (c != null) total = total + spacing;
    if (d != null) total = total + d.height;
    if (d != null) total = total + spacing;
    if (e != null) total = total + e.height;
    if (e != null) total = total + spacing;
    if (f != null) total = total + f.height;
    return total;
  }
}
